package com.jcfk.eam.controller.csm;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jcfk.common.business.log.annotation.RequestLogHeader;
import com.jcfk.common.core.exception.CustomException;
import com.jcfk.common.core.utils.BeanUtils;
import com.jcfk.common.web.domain.*;
import com.jcfk.eam.domain.dto.csm.CsmBindEquipmentDTO;
import com.jcfk.eam.domain.dto.csm.CsmMaterialDataDTO;
import com.jcfk.eam.domain.dto.csm.CsmMaterialDataSaveDTO;
import com.jcfk.eam.domain.dto.csm.CsmProductRecordDTO;
import com.jcfk.eam.domain.po.csm.*;
import com.jcfk.eam.domain.query.csm.CsmMaterialDataQuery;
import com.jcfk.eam.domain.query.csm.CsmProductRecordQuery;
import com.jcfk.eam.service.csm.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.jcfk.common.core.utils.BeanUtils.convertList;

/**
 * 耗材物料主数据表
 *
 * @author awei
 * @email 522891237@gqq.com
 * @date 2024-11-04
 */
@Api(tags = {"耗材物料主数据表管理"})
@RestController
@RequestMapping("csmmaterialdata")
public class  CsmMaterialDataController {
    @Autowired
    private CsmMaterialDataService csmMaterialDataService;

    @Autowired
    private CsmMaterialChildService csmMaterialChildService;

    @Autowired
    private CsmBindEquipmentService csmBindEquipmentService;

    @Autowired
    private CsmWorkRecordService csmWorkRecordService;

    @Autowired
    private CsmProductRecordService csmProductRecordService;

    @Autowired
    private CsmLedgerManageService csmLedgerManageService;


    /**
     * 分页列表
     */
    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "ReqPageParam<CsmMaterialDataQuery>", name = "requestParam", value = "", required = true)})
    @ApiOperation("分页查询耗材物料主数据表")
    @PostMapping("/queryByPage")
    public RetPage<CsmMaterialDataDTO> queryByPage(@RequestBody ReqPageParam<CsmMaterialDataQuery> requestParam) {
        if (requestParam.getSort().getOrderItem() == null) {
            ReqSortParam<CsmMaterialDataQuery> sortParam = new ReqSortParam();
            sortParam.setColumn("lastUpdateTime");
            sortParam.setOrderBy("desc");
            requestParam.setSort(sortParam);
        }
        DataPage<CsmMaterialDataDTO> page = new DataPage<CsmMaterialDataDTO>((long) requestParam.getCurrent(), (long) requestParam.getSize(), requestParam.getSort().getOrderItem(), CsmMaterialDataDTO.class);
        page = csmMaterialDataService.queryByPage(page, requestParam.getData());

        return new RetPage<>(page);
    }


    /**
     * 耗材物料主数据表
     * 根据id 查询详情
     */
    @ApiOperation("查询耗材物料主数据表")
    @GetMapping("/get/{id}")
    public RetResult<CsmMaterialDataDTO> get(@PathVariable("id") String id) {
        CsmMaterialDataDTO item = csmMaterialDataService.get(id);
        return RetResult.ok(item);
    }


    /**
     * 添加/更新管理耗材物料主数据表
     */
    @ApiOperation("保存耗材物料主数据表")
    @PostMapping("/save")
    @RequestLogHeader(modular = "耗材物料主数据表管理", businessType = "保存")
    public RetResult<?> save(@RequestBody @Valid CsmMaterialDataDTO csmMaterialData) {
        // 数据校验
        RetResult ret = csmMaterialDataService.isValid(csmMaterialData);
        if (!ret.getCode().equals(RetResult.SUCCESS)) {
            return ret;
        }
        csmMaterialDataService.insertData(csmMaterialData);
        return RetResult.ok();
    }

    /**
     * 批量删除耗材物料主数据表
     */
    @ApiOperation("批量删除耗材物料主数据表")
    @PostMapping("/delete")
    @RequestLogHeader(modular = "耗材物料主数据表管理", businessType = "批量删除")
    public RetResult<?> delete(@RequestBody CsmMaterialDataDTO csmMaterialData) {
        return RetResult.ok(csmMaterialDataService.logicDeleteList(csmMaterialData));
    }


    /**
     * 删除耗材物料主数据表
     */
    @ApiOperation("删除耗材物料主数据表")
    @PostMapping("/deleteItem/{id}")
    @RequestLogHeader(modular = "耗材物料主数据表管理", businessType = "删除")
    public RetResult<?> deleteItem(@PathVariable("id") String id) {
        csmMaterialDataService.deleteItem(id);
        return RetResult.ok();
    }

    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "MesShiftSetQuery", name = "query", value = "", required = true)})
    @ApiOperation(value = "获取物料列表", notes = "获取物料列表", httpMethod = "POST")
    @PostMapping("getList")
    public RetResult<List<CsmMaterialDataDTO>> getList(@RequestBody CsmMaterialDataQuery query) {
        if (null == query.getDeleted()) query.setDeleted(0);
        query.setParentId("-1");
        if (StrUtil.isEmpty(query.getEnabled())) query.setEnabled("1");
        List<CsmMaterialDataDTO> list = csmMaterialDataService.getList(query);

        return RetResult.ok(list);
    }

    @ApiOperation("耗材编号带出设备-产品-位置列表")
    @GetMapping("/getProduct/{code}")
    public RetResult<?> getProducts(@PathVariable("code") String code) {
        String type = code.substring(0, 3);
        String materialCode = code.substring(3, 10);
        String batchCode = code.substring(10, 16);
        String batchNUm = code.substring(code.length() - 4);
        QueryWrapper<CsmMaterialData> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CsmMaterialData::getMaterialCode, materialCode).eq(CsmMaterialData::getMaterialGroupCode, type);
        List<CsmMaterialData> csmMaterialDatas = csmMaterialDataService.list(queryWrapper);
        List<String> dataIds = csmMaterialDatas.stream().map(CsmMaterialData::getId).collect(Collectors.toList());

        List<CsmBindEquipmentDTO> dtos = new ArrayList<>();
        if (dataIds.size() > 0) {
            QueryWrapper<CsmBindEquipment> bindEquipmentQueryWrapper = new QueryWrapper<>();
            bindEquipmentQueryWrapper.lambda().in(CsmBindEquipment::getMaterialId, dataIds);
            List<CsmBindEquipment> bindEquipments = csmBindEquipmentService.list(bindEquipmentQueryWrapper);

            dtos = convertList(bindEquipments, CsmBindEquipmentDTO.class);
            for (CsmBindEquipmentDTO dto : dtos) {
                dto.setBatchCode(batchCode);
                dto.setBatchNUm(Integer.valueOf(batchNUm));
            }
        }
        return RetResult.ok(dtos);
    }

    @ApiOperation("耗材编号带出耗材子项列表")
    @GetMapping("/getRecord/{dataid}")
    public RetResult<?> getRecord(@PathVariable("dataid") String dataid) {
        // 判断有没有子 有子显示子 没有子显示自己
        List<CsmMaterialDataDTO> dataDTOS = new ArrayList<>();
        List<CsmMaterialData> dataList = new ArrayList<>();
        QueryWrapper<CsmProductRecord> productRecordQueryWrapper = new QueryWrapper<>();
        QueryWrapper<CsmMaterialData> queryWrapper = new QueryWrapper<>();
        // 判断有没有子 有子显示子 没有子显示自己
        queryWrapper.lambda().eq(CsmMaterialData::getId, dataid);
        CsmMaterialData csmMaterialData = csmMaterialDataService.getOne(queryWrapper);
        if(null == csmMaterialData.getChildNum() || csmMaterialData.getChildNum()==0) {
            dataList.add(csmMaterialData);
        }else{
            QueryWrapper<CsmMaterialData> queryWrapperChild = new QueryWrapper<>();
            queryWrapperChild.lambda().eq(CsmMaterialData::getParentId, dataid);
            dataList = csmMaterialDataService.list(queryWrapperChild);
        }
        List<String> ids = dataList.stream().map(CsmMaterialData::getId).collect(Collectors.toList());

        // 生产使用中的不能再选
        productRecordQueryWrapper.lambda().in(CsmProductRecord::getMaterialId, ids).ne(CsmProductRecord::getStatus, 1);
        List<CsmProductRecord> records = csmProductRecordService.list(productRecordQueryWrapper);
        List<String> mids = records.stream().map(CsmProductRecord::getMaterialId).collect(Collectors.toList());
        if (mids.size() > 0) {
            List<CsmMaterialData> filterList = dataList.stream().filter(item->!mids.contains(item.getId())).collect(Collectors.toList());
            dataDTOS = convertList(filterList, CsmMaterialDataDTO.class);
        }else{
            dataDTOS = convertList(dataList, CsmMaterialDataDTO.class);
        }
        productRecordQueryWrapper.select("SUM( work_count ) workCount,SUM( work_life ) workLife,material_id materialId").groupBy("material_id");
        List<Map<String, Object>> maps = csmProductRecordService.listMaps(productRecordQueryWrapper);
        Map<String, Map<String, Object>> map = new HashMap<>();
        for (Map<String, Object> nowmap : maps) {
            BigDecimal one = new BigDecimal("1");
            BigDecimal bigDecimal = new BigDecimal(nowmap.get("workLife").toString());
            BigDecimal result = one.subtract(bigDecimal);
            nowmap.put("remaining", result);
            map.put(nowmap.get("materialId").toString(), nowmap);
        }

        for (CsmMaterialDataDTO dataDTO : dataDTOS) {
            Map<String, Object> objectMap = map.get(dataDTO.getId());
            if (objectMap != null) {
                dataDTO.setRemaining((BigDecimal) objectMap.get("remaining"));
                dataDTO.setWorkCount((Integer) objectMap.get("workCount"));
                dataDTO.setWorkLife((BigDecimal) objectMap.get("workLife"));
            } else {
                dataDTO.setRemaining(new BigDecimal(1));
                dataDTO.setWorkCount(0);
                dataDTO.setWorkLife(new BigDecimal(0));
            }
        }
        return RetResult.ok(dataDTOS);
    }


    /**
     * 添加/更新管理耗材物料主数据表
     */
    @ApiOperation("保存耗材安装")
    @PostMapping("/insert")
    @RequestLogHeader(modular = "耗材物料主数据表管理", businessType = "保存")
    public RetResult<?> insert(@RequestBody @Valid CsmMaterialDataSaveDTO csmMaterialData) {
        CsmBindEquipmentDTO csmBindEquipment = csmMaterialData.getCsmBindEquipment();
        for (int i = 0; i < csmMaterialData.getDataDTOS().size(); i++) {
            CsmMaterialDataDTO dataDTO = csmMaterialData.getDataDTOS().get(i);
            String consumeCode = csmMaterialData.getConsumeCode();
            String consumeCodeP = consumeCode;
            if(!"-1".equals(dataDTO.getParentId())){
                // 耗材挂件表
                consumeCode = consumeCode+ "-" + i+1;
            }
            QueryWrapper<CsmProductRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(CsmProductRecord::getMaterialId, dataDTO.getId());
            CsmProductRecord csmProductRecord = csmProductRecordService.getOne(queryWrapper);
            if (csmProductRecord == null) {
                csmProductRecord = new CsmProductRecord();
                csmProductRecord.setUpTime(new Date());
                csmProductRecord.setConsumeCode(consumeCode);
                csmProductRecord.setStatus("2");
                csmProductRecord.setProductCode(csmBindEquipment.getProductCode());
                csmProductRecord.setEquipPosition(csmBindEquipment.getEquipPosition());
                csmProductRecord.setWorkLife(new BigDecimal(0));
                csmProductRecord.setWorkCount(0);
                csmProductRecord.setMaterialId(dataDTO.getId());
                csmProductRecord.setEquipCode(csmBindEquipment.getEquipCode());
                csmProductRecordService.setDefaultValue(csmProductRecord);
                csmProductRecordService.save(csmProductRecord);
                if("-1".equals(dataDTO.getParentId())){
                    CsmLedgerManage csmLedgerManage = new CsmLedgerManage();
                    csmLedgerManage.setBatchInfo(csmMaterialData.getCsmBindEquipment().getBatchCode());
                    csmLedgerManage.setBatchCount(csmMaterialData.getCsmBindEquipment().getBatchNUm());
                    csmLedgerManage.setPid("0");
                    csmLedgerManage.setMaterialId(dataDTO.getId());
                    csmLedgerManage.setProductRecordId(csmProductRecord.getId());
                    csmLedgerManage.setEquipPosition(csmBindEquipment.getEquipPosition());
                    csmLedgerManage.setConsumeCode(consumeCode);
                    csmLedgerManage.setStatus("2");
                    csmLedgerManage.setEquipPosition(csmBindEquipment.getEquipPosition());
                    csmLedgerManage.setWorkLife(new BigDecimal(0));
                    csmLedgerManage.setWorkCount(0);
                    csmLedgerManage.setEquipCode(csmBindEquipment.getEquipCode());
                    csmLedgerManageService.setDefaultValue(csmLedgerManage);
                    csmLedgerManageService.save(csmLedgerManage);
                } else {
                    // 子的，存树形
                    QueryWrapper<CsmLedgerManage> queryWrapperE = new QueryWrapper<>();
                    queryWrapperE.lambda().eq(CsmLedgerManage::getMaterialId, dataDTO.getParentId());
                    CsmLedgerManage csmLedgerManageE = csmLedgerManageService.getOne(queryWrapperE);
                    CsmLedgerManage csmLedgerManage = new CsmLedgerManage();
                    if (csmLedgerManageE == null) {
                        csmLedgerManage.setBatchInfo(csmMaterialData.getCsmBindEquipment().getBatchCode());
                        csmLedgerManage.setBatchCount(csmMaterialData.getCsmBindEquipment().getBatchNUm());
                        csmLedgerManage.setPid("0");
                        csmLedgerManage.setMaterialId(dataDTO.getParentId());
                        csmLedgerManage.setProductRecordId(csmProductRecord.getId());
                        csmLedgerManage.setEquipPosition(csmBindEquipment.getEquipPosition());
                        csmLedgerManage.setConsumeCode(consumeCodeP);
                        csmLedgerManage.setStatus("2");
                        csmLedgerManage.setEquipPosition(csmBindEquipment.getEquipPosition());
                        csmLedgerManage.setWorkLife(new BigDecimal(0));
                        csmLedgerManage.setWorkCount(0);
                        csmLedgerManage.setEquipCode(csmBindEquipment.getEquipCode());
                        csmLedgerManageService.setDefaultValue(csmLedgerManage);
                        csmLedgerManageService.save(csmLedgerManage);
                    }else{
                        BeanUtils.copyProperties(csmLedgerManageE, csmLedgerManage);
                    }

                    CsmLedgerManage csmLedgerManageSon = new CsmLedgerManage();
                    csmLedgerManage.setBatchInfo(csmMaterialData.getCsmBindEquipment().getBatchCode());
                    csmLedgerManage.setBatchCount(csmMaterialData.getCsmBindEquipment().getBatchNUm());
                    csmLedgerManageSon.setPid(csmLedgerManage.getId());
                    csmLedgerManageSon.setMaterialId(dataDTO.getId());
                    csmLedgerManageSon.setProductRecordId(csmProductRecord.getId());
                    csmLedgerManageSon.setEquipPosition(csmBindEquipment.getEquipPosition());
                    csmLedgerManageSon.setConsumeCode(consumeCode);
                    csmLedgerManageSon.setStatus("2");
                    csmLedgerManageSon.setEquipPosition(csmBindEquipment.getEquipPosition());
                    csmLedgerManageSon.setWorkLife(new BigDecimal(0));
                    csmLedgerManageSon.setWorkCount(0);
                    csmLedgerManageSon.setEquipCode(csmBindEquipment.getEquipCode());
                    csmLedgerManageService.setDefaultValue(csmLedgerManageSon);
                    csmLedgerManageService.save(csmLedgerManageSon);
                }
            } else {
                csmProductRecord.setStatus("2");
                csmProductRecordService.setDefaultValue(csmProductRecord);
                csmProductRecordService.updateById(csmProductRecord);

                QueryWrapper<CsmLedgerManage> childQueryWrapper = new QueryWrapper<>();
                childQueryWrapper.lambda().eq(CsmLedgerManage::getProductRecordId, csmProductRecord.getId());
                CsmLedgerManage csmLedgerManage = new CsmLedgerManage();
                csmLedgerManage.setStatus("2");
                csmLedgerManageService.update(csmLedgerManage, childQueryWrapper);
            }

            CsmWorkRecord csmWorkRecord = new CsmWorkRecord();
            csmWorkRecord.setMaterialId(dataDTO.getId());
            csmWorkRecord.setWorkType("1");
            csmWorkRecord.setWorkStatus("2");
            csmWorkRecord.setWorkLife(csmProductRecord.getWorkLife());
            csmWorkRecord.setWorkCount(csmProductRecord.getWorkCount());
            csmWorkRecord.setConsumeCode(consumeCode);
            csmWorkRecord.setUpTime(new Date());
            csmWorkRecord.setProductRecordId(csmProductRecord.getId());

            csmWorkRecordService.setDefaultValue(csmWorkRecord);
            csmWorkRecordService.save(csmWorkRecord);
        }
        return RetResult.ok();
    }

    @GetMapping("/getRecordList/{code}")
    public RetResult<?> getRecordList(@PathVariable("code") String code) {
        Map<String, Object> map = new HashMap<>();

        QueryWrapper<CsmProductRecord> csmWorkRecordQueryWrapper = new QueryWrapper<>();
        csmWorkRecordQueryWrapper.lambda().likeRight(!StrUtil.isEmpty(code), CsmProductRecord::getConsumeCode, code);
        csmWorkRecordQueryWrapper.lambda().eq(CsmProductRecord::getStatus, "2");
        List<CsmProductRecord> list = csmProductRecordService.list(csmWorkRecordQueryWrapper);
        List<CsmProductRecordDTO> dtos = convertList(list, CsmProductRecordDTO.class);

        if (dtos.size() == 0) {
            throw new CustomException("该耗材编码未找到使用中的耗材！");
        } else {
            for (int i = 0; i < dtos.size(); i++) {
                CsmProductRecordDTO dto = dtos.get(i);
                QueryWrapper<CsmWorkRecord> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("TOP 1 *");
                queryWrapper.lambda().eq(CsmWorkRecord::getProductRecordId, dto.getId());
                queryWrapper.lambda().orderByDesc(CsmWorkRecord::getCreateTime);
                CsmWorkRecord csmWorkRecord = csmWorkRecordService.getOne(queryWrapper);
                if (csmWorkRecord != null) dto.setLastWorkLife(csmWorkRecord.getWorkLife());
                if (i == 0) {
                    map.put("equipPosition", dto.getEquipPosition());
                    map.put("productCode", dto.getConsumeCode());
                    map.put("equipCode", dto.getEquipCode());
                }
            }
        }
        map.put("list", dtos);
        return RetResult.ok(map);
    }


    @PostMapping("/updateMaterialList")
    public RetResult<?> updateMaterialList(@RequestBody CsmProductRecordDTO dto) {
        for (String id : dto.getIds()) {
            CsmProductRecord csmProductRecor = csmProductRecordService.getById(id);
            csmProductRecor.setStatus(dto.getStatus());
            csmProductRecor.setDownTime(new Date());
            csmProductRecor.setDownTime(new Date());
            csmProductRecordService.setDefaultValue(csmProductRecor);
            csmProductRecordService.updateById(csmProductRecor);

            QueryWrapper<CsmLedgerManage> childQueryWrapper = new QueryWrapper<>();
            childQueryWrapper.lambda().eq(CsmLedgerManage::getProductRecordId, id);
            CsmLedgerManage csmLedgerManage = new CsmLedgerManage();
            csmLedgerManage.setStatus(dto.getStatus());
            csmLedgerManageService.update(csmLedgerManage, childQueryWrapper);

            CsmWorkRecord csmWorkRecord = new CsmWorkRecord();
            csmWorkRecord.setMaterialId(csmProductRecor.getMaterialId());
            if (dto.getStatus().equals("2")) {
                csmWorkRecord.setWorkType("1");
                csmWorkRecord.setUpTime(new Date());
            } else if (dto.getStatus().equals("1")) {
                csmWorkRecord.setWorkType("2");
                csmWorkRecord.setDownTime(new Date());
            } else {
                csmWorkRecord.setWorkStatus("3");
                csmWorkRecord.setDownTime(new Date());
            }
            csmWorkRecord.setWorkStatus(dto.getStatus());
            csmWorkRecord.setWorkLife(csmProductRecor.getWorkLife());
            csmWorkRecord.setWorkCount(csmProductRecor.getWorkCount());

            csmWorkRecord.setRemarks(dto.getRemarks());
            csmWorkRecord.setProductRecordId(csmProductRecor.getId());
            csmWorkRecordService.setDefaultValue(csmWorkRecord);
            csmWorkRecordService.save(csmWorkRecord);
        }
        return RetResult.ok();
    }

    @GetMapping("/getAbnormalRecordList/{code}")
    public RetResult<?> getAbnormalRecordList(@PathVariable("code") String code) {
        QueryWrapper<CsmProductRecord> csmWorkRecordQueryWrapper = new QueryWrapper<>();
        csmWorkRecordQueryWrapper.lambda().eq(!StringUtils.isEmpty(code), CsmProductRecord::getConsumeCode, code);
        csmWorkRecordQueryWrapper.lambda().eq(CsmProductRecord::getStatus, "3").or().eq(CsmProductRecord::getStatus, "4");
        List<CsmProductRecord> list = csmProductRecordService.list(csmWorkRecordQueryWrapper);
        List<CsmProductRecordDTO> dtos = convertList(list, CsmProductRecordDTO.class);
        return RetResult.ok(dtos);
    }


    /**
     * 分页列表
     */
    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "ReqPageParam<CsmProductRecordQuery>", name = "requestParam", value = "", required = true)})
    @ApiOperation("分页查询耗材生产记录")
    @PostMapping("/getByPage")
    public RetPage<CsmProductRecordDTO> getByPage(@RequestBody ReqPageParam<CsmProductRecordQuery> requestParam) {
        // 设置默认排序
        if (requestParam.getSort().getOrderItem() == null) {
            ReqSortParam<CsmProductRecordQuery> sortParam = new ReqSortParam();
            sortParam.setColumn("lastUpdateTime");
            sortParam.setOrderBy("desc");
            requestParam.setSort(sortParam);
        }
        DataPage<CsmProductRecordDTO> page = new DataPage<CsmProductRecordDTO>((long) requestParam.getCurrent(), (long) requestParam.getSize(), requestParam.getSort().getOrderItem(), CsmProductRecordDTO.class);
        requestParam.getData().setPdstatus("2");

        if (!StringUtils.isEmpty(requestParam.getData().getSearchData())) {
            requestParam.getData().setSearchData("%" + requestParam.getData().getSearchData() + "%");
        }
        page = csmProductRecordService.queryByPage(page, requestParam.getData());

        return new RetPage<>(page);
    }


}
